#include "token.h"
#include "input.h"
#include "state.h"
#include "statemachine.h"

   

StateMachine::StateMachine()
{
	_state_map[START] = new STStart;
	_state_map[INT] = new STInt;
	_state_map[FLOAT] = new STFloat;
	_state_map[IDENT] = new STIdent;
	_state_map[OP] = new STOp;
	_state_map[STRING] = new STString;
	_state_map[COMMENTLINE] = new STLineComment;
	_state_map[INVALID] = new STInvalid;
	
	if(!setInitState(START)) {
	    printf("set Init State Falied!\n");
	}    
}



StateMachine::~StateMachine()
{
	map<LEX_STATE, State*>::iterator Iter = _state_map.begin();
	while (Iter != _state_map.end()) {
		delete (Iter->second);
		++Iter;
	}
}


bool StateMachine::hasState(LEX_STATE lst)
{
     map<LEX_STATE, State*>::iterator Iter = _state_map.find(lst);
	 if (Iter == _state_map.end())
		return false;

     return true;
}


bool StateMachine::setInitState(LEX_STATE lst)
{
   if (!hasState(lst))
      return false;
		
	_initState = lst;
	return true;
}
    

Token StateMachine::getToken()  
{ 
	if (!hasState(_state)) {
	    fprintf(stderr, "State Not Exist!\n");
        return TOKEN_INVALID;
	}
     
    State *p = _state_map[_state];
    
    if (p == NULL) {
        fprintf(stderr, "State pointer is NULL!\n");
        return TOKEN_INVALID;
    }    
    
    return p->token(); 
}


bool StateMachine::registState(LEX_STATE lst, State *state)
{
	if (hasState(_state)) 
		return false;

	_state_map[lst] = state;
	return true;
}


bool StateMachine::accept(OutputStream &out, InputStream &in, int ch)
{
    if (!hasState(_state)) {
	    fprintf(stderr, "State Not Exist!\n");
        return false;
	}
	
    State *p = _state_map[_state];
    
    if (p == NULL) {
        fprintf(stderr, "State pointer is NULL!\n");
        return false;
    }    
    
    return p->accept(out, in, *this, ch); 
}
